package com.example.flutteruikit;

import android.text.TextUtils;

public class HexUtil {

    public static byte[] hex2Bytes(String hex) {
        if (TextUtils.isEmpty(hex)) {
            return null;
        }
        String value = hex.replaceAll(" ", "").trim();
        if (TextUtils.isEmpty(value)) {
            return null;
        } else if (value.length() % 2 != 0) {
            value = "0" + value;
        }
        value = value.toUpperCase();
        int len = value.length() / 2;
        byte[] b = new byte[len];
        char[] hc = value.toCharArray();
        for (int i = 0; i < len; i++) {
            int p = 2 * i;
            b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1]));
        }
        return b;
    }

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static String byte2Hex(byte src) {
        StringBuilder ret = new StringBuilder();
        String hex = Integer.toHexString(src & 0xFF);
        if (hex.length() < 2) {
            hex = "0" + hex;
        }
        ret.append(hex);
        return ret.toString().toUpperCase();
    }

    public static void inverted(byte[] bytes) {
        byte temp;
        for (int i = 0; i < bytes.length / 2; i++) {
            temp = bytes[i];
            bytes[i] = bytes[bytes.length - 1 - i];
            bytes[bytes.length - 1 - i] = temp;
        }
    }

    public static String inverted(String value) {
        if (TextUtils.isEmpty(value)) {
            return null;
        }
        if (value.length() % 2 != 0) {
            value += "0";
        }
        int length = value.length() / 2;

        StringBuilder result = new StringBuilder();
        for (int i = 0; i < length; i++) {
            result.insert(0, value.substring(i * 2, i * 2 + 2));
        }

        return result.toString();
    }

    public static String byteToHex(byte src) {
        StringBuilder str = new StringBuilder();
        str.append(bitToHex((src >> 4) & 0x0F));
        str.append(bitToHex(src & 0x0F));
        return str.toString().toUpperCase();
    }

    public static String bytesToHex(byte[] data) {
        return bytesToHex(data, "");
    }

    public static String bytesToHex(byte[] data, String insert) {
        if (data == null) {
            return "";
        }

        StringBuilder str = new StringBuilder();
        for (byte b : data) {
            str.append(byteToHex(b));
            str.append(insert);
        }
        return str.toString();
    }

    private static char bitToHex(int bit) {
        if (bit >= 0 && bit <= 9) {
            return (char) ((int) '0' + bit);
        } else if (bit >= 10 && bit <= 15) {
            return (char) ((int) 'A' + bit - 10);
        } else {
            return '-';
        }
    }

    public static byte[] byteMerge(byte[] byte1, byte[] byte2) {
        byte[] mergeByte = new byte[byte1.length + byte2.length];
        System.arraycopy(byte1, 0, mergeByte, 0, byte1.length);
        System.arraycopy(byte2, 0, mergeByte, byte1.length, byte2.length);
        return mergeByte;
    }

    public static byte[] intToByte(int value) {
        byte[] arr = new byte[4];
        arr[3] = (byte) (value & 0xff);
        arr[2] = (byte) ((value >> 8) & 0xff);
        arr[1] = (byte) ((value >> 16) & 0xff);
        arr[0] = (byte) ((value >> 24) & 0xff);
        return arr;
    }

    public static int byteToInt(byte[] bytes) {
        return (bytes[0] & 0xff) << 24
                | (bytes[1] & 0xff) << 16
                | (bytes[2] & 0xff) << 8
                | (bytes[3] & 0xff);
    }

    public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
        if (array == null) {
            return -1;
        }
        if (startIndex < 0) {
            startIndex = 0;
        }
        for (int i = startIndex; i < array.length; i++) {
            if (valueToFind == array[i]) {
                return i;
            }
        }
        return -1;
    }
}
